home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Stream / Var.php < prev   
PHP Script  |  2004-03-24  |  13KB  |  465 lines

  1. <?PHP
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stephan Schmidt <schst@php-tools.net>                       |
  17. // |          partly based on an exmple by Wez Furlong                    |
  18. // +----------------------------------------------------------------------+
  19. //
  20. //    $Id$
  21.  
  22. /**
  23.  * stream is readable
  24.  * This depends on the mode, that is used for opening the stream
  25.  */
  26. define("STREAM_VAR_READABLE", 1);
  27.  
  28. /**
  29.  * stream is writeable
  30.  * This depends on the mode, that is used for opening the stream
  31.  */
  32. define("STREAM_VAR_WRITEABLE", 2);
  33.  
  34. /**
  35.  * Stream wrapper to access a variable
  36.  *
  37.  * Stream wrappers allow you to access any datasource using PHP's file manipulation functions
  38.  * like fopen(), fclose(), fseek(), ftell(),.. as well as directory functions like 
  39.  * opendir() readdir() and closedir().
  40.  *
  41.  * This wrapper allows you to access any variable using these functions.
  42.  * You have to specify a scope (GLOBALS, _GET, _POST, etc.) as the host and
  43.  * the variable name as the path. If you want to access a string, that is
  44.  * stored in an array, you can use this array like you would use a directory.
  45.  *
  46.  * Usage:
  47.  * <code>
  48.  *  require_once '../Var.php';
  49.  *  stream_wrapper_register( "var", "Stream_Var" );
  50.  *
  51.  *  $fp = fopen('var://GLOBALS/myArray/index','r');
  52.  *  $data = fread($fp,100);
  53.  *  fclose($fp);
  54.  * </code>
  55.  *
  56.  * This wrapper also has support for dir functions, so it's possible to read any array, like
  57.  * you would read a directory. The following code will list all keys in an array.
  58.  * You could use fopen() to read the values for the keys.
  59.  *
  60.  * <code>
  61.  *  require_once '../Var.php';
  62.  *  stream_wrapper_register( "var", "Stream_Var" );
  63.  *
  64.  *  $dh = opendir('var://_SERVER');
  65.  *  while ($entry = readdir($dh)) {
  66.  *      echo $entry."<br />";
  67.  *  }
  68.  *  closedir($dh);
  69.  * </code>
  70.  *
  71.  * This wrapper allows you to replace files and directories with structures in
  72.  * memory in any application, that relies on filesystem functions. But keep in mind
  73.  * that variables are not persistent during several request, unless you write to
  74.  * var://SESSION.
  75.  * But this can be used to replace temporary files with variables.
  76.  *
  77.  * @category Stream
  78.  * @package  Stream_Var
  79.  * @version  0.2.1
  80.  * @author   Stephan Schmidt <schst@php-tools.net>
  81.  */
  82. class Stream_Var {
  83.  
  84.    /**
  85.     * pointer to the variable
  86.     * @var mixed   $_pointer
  87.     */
  88.     var $_pointer = null;
  89.  
  90.    /**
  91.     * flag to indicate whether stream is open
  92.     * @var boolean   $_open
  93.     */
  94.     var $_open = false;
  95.  
  96.    /**
  97.     * position
  98.     * @var integer $_pos
  99.     */
  100.     var $_pos = 0;
  101.  
  102.    /**
  103.     * mode of the opened filw
  104.     * @var integer   $_mode
  105.     */
  106.     var $_mode = 0;
  107.  
  108.    /**
  109.     * method used by fopen
  110.     *
  111.     * @access public
  112.     * @param  string  $path        path to the variable (e.g. var://GLOBALS/myArray/anyIndex)
  113.     * @param  string  $mode        mode to open the stream, like 'r', 'w,',... ({@see fopen()})
  114.     * @param  array   $options     options (not implemented yet)
  115.     * @param  string  $opened_path this will be set to the actual opened path
  116.     * @return boolean $success
  117.     */
  118.     function stream_open($path, $mode, $options, &$opened_path)
  119.     {
  120.         $url = parse_url($path);
  121.  
  122.         $scope   = $url["host"];
  123.         $varpath = substr($url["path"], 1);
  124.         
  125.         $mode = strtolower($mode);
  126.         switch ($mode{0}) {
  127.             case    "r":
  128.                 $status = $this->_setPointer($scope, $varpath, false);
  129.                 $this->_mode = $this->_mode | STREAM_VAR_READABLE;
  130.                 break;
  131.             case    "w":
  132.             case    "a":
  133.                 $status = $this->_setPointer($scope, $varpath, true);
  134.                 $this->_mode = $this->_mode | STREAM_VAR_WRITEABLE;
  135.                 break;
  136.             case    "x":
  137.                 $status = $this->_setPointer($scope, $varpath, false);
  138.                 if ($status) {
  139.                     return false;
  140.                 }
  141.                 $status = $this->_setPointer($scope, $varpath, true);
  142.                 $this->_mode = $this->_mode | STREAM_VAR_WRITEABLE;
  143.                 break;
  144.         }
  145.  
  146.         if (!$status)
  147.             return  false;
  148.         
  149.         if (!is_scalar($this->_pointer)) {
  150.             return false;
  151.         }
  152.  
  153.         // start at zero
  154.         $this->_pos = 0;
  155.         $this->_open = true;
  156.         $opened_path = $path;
  157.  
  158.         if ($mode{0} == 'a') {
  159.             $this->stream_seek(0, SEEK_END);
  160.         }
  161.  
  162.         if ($mode{1} == '+') {
  163.             $this->_mode = $this->_mode | STREAM_VAR_READABLE | STREAM_VAR_WRITEABLE;
  164.         }
  165.  
  166.         return true;
  167.     }
  168.  
  169.    /**
  170.     * check for end of stream
  171.     *
  172.     * @access public
  173.     * @return boolean $eof  true if at end of stream
  174.     */
  175.     function stream_eof()
  176.     {
  177.         return ($this->_pos >= strlen($this->_pointer));
  178.     }
  179.  
  180.    /**
  181.     * return the current position
  182.     *
  183.     * @access public
  184.     * @return integer $position current position in stream
  185.     */
  186.     function stream_tell()
  187.     {
  188.         return $this->_pos;
  189.     }
  190.  
  191.    /**
  192.     * close the stream
  193.     *
  194.     * @access public
  195.     */
  196.     function stream_close()
  197.     {
  198.         $this->_pos     = 0;
  199.         $this->_open    = false;
  200.     }
  201.  
  202.    /**
  203.     * read from the stream
  204.     *
  205.     * @access public
  206.     * @param  integer $count    amount of bytes to read
  207.     * @return string  $data     data that has been read
  208.     */
  209.     function stream_read($count)
  210.     {
  211.         if (!$this->_open) {
  212.             return false;
  213.         }
  214.  
  215.         if (!($this->_mode & STREAM_VAR_READABLE)) {
  216.             return false;
  217.         }
  218.  
  219.         $data = substr($this->_pointer, $this->_pos, $count);
  220.         $this->_pos = $this->_pos + strlen($data);
  221.         return $data;
  222.     }
  223.  
  224.    /**
  225.     * write to the stream
  226.     *
  227.     * @access public
  228.     * @param  mixed   $data  data to write
  229.     * @return integer $bytes number of bytes that were written
  230.     */
  231.     function stream_write($data)
  232.     {
  233.         if (!$this->_open) {
  234.             return false;
  235.         }
  236.         
  237.         if (!($this->_mode & STREAM_VAR_WRITEABLE)) {
  238.             return false;
  239.         }
  240.         
  241.         $datalen = strlen($data);
  242.        
  243.         $this->_pointer = substr($this->_pointer, 0, $this->_pos) . $data . substr($this->_pointer, $this->_pos+$datalen);
  244.         $this->_pos = $this->_pos + $datalen;
  245.         return $datalen;
  246.     }
  247.  
  248.    /**
  249.     * move the position in the stream
  250.     *
  251.     * @access public
  252.     * @param  integer $offset  offset
  253.     * @return integer $whence  point from which the offset should be calculated
  254.     */
  255.     function stream_seek($offset, $whence)
  256.     {
  257.         switch ($whence) {
  258.             //  from start
  259.             case SEEK_SET:
  260.                 if ($offset < strlen($this->_pointer) && $offset >= 0) {
  261.                      $this->_pos = $offset;
  262.                      return true;
  263.                 } else {
  264.                      return false;
  265.                 }
  266.                 break;
  267.             // from current position
  268.             case SEEK_CUR:
  269.                 if ($offset >= 0) {
  270.                      $this->_pos += $offset;
  271.                      return true;
  272.                 } else {
  273.                      return false;
  274.                 }
  275.                 break;
  276.             // from the end
  277.             case SEEK_END:
  278.                 if (strlen($this->_pointer) + $offset >= 0) {
  279.                      $this->_pos = strlen($this->_pointer) + $offset;
  280.                      return true;
  281.                 } else {
  282.                      return false;
  283.                 }
  284.                 break;
  285.             default:
  286.                 return false;
  287.         }
  288.     }
  289.  
  290.    /**
  291.     * write all data to storage
  292.     *
  293.     * @access public
  294.     */
  295.     function stream_flush()
  296.     {
  297.         return true;
  298.     }
  299.  
  300.    /**
  301.     * return information about the stream
  302.     *
  303.     * @access public
  304.     * @return array $stat   information about the stream (currently only the length is included)
  305.     */
  306.     function stream_stat()
  307.     {
  308.         $stat = array(
  309.                       "size" => strlen($this->_pointer)
  310.                     );
  311.         return $stat;
  312.     }
  313.  
  314.  
  315.    /**
  316.     * open 'directory'
  317.     *
  318.     * @access public
  319.     * @param  string    $path    path to the array (i.e. the directory)
  320.     * @param  array     $options not implemented, yet.
  321.     * @return boolean   $success
  322.     */
  323.     function dir_opendir($path, $options)
  324.     {
  325.         $url = parse_url($path);
  326.  
  327.         $scope   = $url["host"];
  328.         $varpath = substr($url["path"], 1);
  329.         
  330.         if (!$status = $this->_setPointer($scope, $varpath))
  331.             return  false;
  332.  
  333.         if (!is_array($this->_pointer)) {
  334.             return false;
  335.         }
  336.         reset($this->_pointer);
  337.         $this->_open = true;
  338.         return true;
  339.     }
  340.  
  341.  
  342.    /**
  343.     * close 'directory'
  344.     *
  345.     * @access public
  346.     * @return boolean $success
  347.     */
  348.     function dir_closedir()
  349.     {
  350.         $this->_open = false;
  351.         return true;
  352.     }
  353.  
  354.    /**
  355.     * rewind 'directory'
  356.     *
  357.     * @access public
  358.     * @return boolean $success
  359.     */
  360.     function dir_rewinddir()
  361.     {
  362.         if (!$this->_open) {
  363.             return false;
  364.         }
  365.         reset($this->_pointer);
  366.         return true;
  367.     }
  368.  
  369.    /**
  370.     * read one entry from 'directory'
  371.     *
  372.     * @access public
  373.     * @return mixed  $entry entry that has been read, or false if there are no entries left  
  374.     */
  375.     function dir_readdir()
  376.     {
  377.         if (!$this->_open) {
  378.             return false;
  379.         }
  380.         if (current($this->_pointer) == count($this->_pointer)-1) {
  381.             return false;
  382.         }
  383.         list($key) = each($this->_pointer);
  384.         return $key;
  385.     }
  386.  
  387.    /**
  388.     * set the internal pointer
  389.     *
  390.     * Basically this method only sets the object property _pointer
  391.     * as a reference to a variable
  392.     *
  393.     * @access private
  394.     * @param  string  $scope    scope of the variable: GLOBAL, GET, POST, COOKIE, SESSION, SERVER, ENV
  395.     * @param  string  $path     path to the variable. Array indices are seperated by a slash
  396.     * @param  boolean $create   create the variable, if it does not exist
  397.     */
  398.     function _setPointer($scope, $path, $create = false )
  399.     {
  400.         $varpath = explode("/", $path);
  401.  
  402.         switch (strtoupper($scope)) {
  403.             // GET variables
  404.             case    "GET":
  405.             case    "_GET":
  406.                 $this->_pointer = &$_GET;
  407.                 break;
  408.  
  409.             // POST variables
  410.             case    "POST":
  411.             case    "_POST":
  412.                 $this->_pointer = &$_POST;
  413.                 break;
  414.  
  415.             // SERVER variables
  416.             case    "SERVER":
  417.             case    "_SERVER":
  418.                 $this->_pointer = &$_SERVER;
  419.                 break;
  420.  
  421.             // SESSION variables
  422.             case    "SESSION":
  423.             case    "_SESSION":
  424.                 $this->_pointer = &$_SESSION;
  425.                 break;
  426.  
  427.             // COOKIE variables
  428.             case    "COOKIE":
  429.             case    "_COOKIE":
  430.                 $this->_pointer = &$_COOKIE;
  431.                 break;
  432.  
  433.             // ENV variables
  434.             case    "ENV":
  435.             case    "_ENV":
  436.                 $this->_pointer = &$_ENV;
  437.                 break;
  438.  
  439.             // global variables
  440.             case    "GLOBALS":
  441.             default:
  442.                 $this->_pointer = &$GLOBALS;
  443.                 break;
  444.             
  445.         }
  446.         if (empty($varpath)) {
  447.             return true;
  448.         }
  449.  
  450.         while ($part = array_shift($varpath)) {
  451.             if (!isset($this->_pointer[$part])) {
  452.                 if (!$create) {
  453.                     return false;
  454.                 }
  455.                 if (!empty($varpath)) {
  456.                     return false;
  457.                 }
  458.                 $this->_pointer[$part] = '';
  459.             }
  460.             $this->_pointer = &$this->_pointer[$part];
  461.         }        
  462.         return true;
  463.     }
  464. }
  465. ?>